<!DOCTYPE html>
<!--
  Copyright 2010 Google Inc.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<html>
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.0/jquery-ui.min.js"></script>
    <style>
      canvas {
        position: absolute;
        left: 10px;
        top: 10px;
        z-index: 1;
      }
      #controls {
        position: absolute;
        left: 520px;
      }
      ul {
        list-style-type: none;
        margin: 0;
        padding: 0;
      }
      li {
        cursor: move;
        font: 14px Arial;
        background: #eee;
        padding: 4px;
        margin: 2px;
        border: 1px solid #ccc;
      }
      li img {
        width: 50px;
        height: 40px;
        margin-left: 20px;
      }
    </style>
    <script>
      function getHandle(layer) {
        return $('li[layer=' + layer + ']').get(0);
      };
      function getCanvas(layer) {
        return $('canvas[layer=' + layer + ']').get(0);
      };
      function getRandInt(max) {
        return Math.floor(Math.random() * max);
      };
      function initCanvas(canvas) {
        var context = canvas.getContext("2d");
        var layer = canvas.getAttribute('layer');
        var handle = $('<li class="handle" layer="' + layer + '">' +
                       'Layer ' + layer + 
                       '<img />' +
                       '</li>');
        $('#dom_handles').append(handle);
        
        canvas.width = 500;
        canvas.height = 400;
        //context.fillStyle = '#'+Math.floor(Math.random()*16777215).toString(16);
        context.fillStyle = 'rgba(' + getRandInt(255) + ',' + 
                                      getRandInt(255) + ',' +
                                      getRandInt(255) + ',' + 
                                      Math.random() + ')';
        var x = getRandInt(400);
        var y = getRandInt(300);
        var w = getRandInt(200) + 300;
        var h = getRandInt(200) + 200;
        context.fillRect(x, y, w, h);
        handle.find('img').attr('src', canvas.toDataURL());
      };
      function setLayerOrder() {
        $('li[layer]').each(function(index, item) {
          var layer = item.getAttribute('layer');
          var depth = 100 - index;
          var target_canvas = $('canvas[layer=' + layer + ']');
          target_canvas.css('z-index', depth);          
        });
      };
      function getCompAlpha(a1, a2) {
        if (a1 == 0) return a2;
        if (a2 == 0) return a1;
        
        var alpha1 = a1 / 255;
        var alpha2 = a2 / 255;
        
        var alpha3 = alpha2 + alpha1 - alpha1 * alpha2;
        return Math.min(255, Math.max(0, alpha3 * 255));
      };
      function getCompColor(c1, a1, c2, a2, a3) {
        if (a1 == 0) return c2;
        if (a2 == 0) return c1;
        
        var alpha1 = a1 / 255;
        var alpha2 = a2 / 255;
        var alpha3 = a3 / 255;

        var c3prime = alpha2 * c2 + alpha1 * c1 - alpha2 * alpha1 * c1;
        var c3 = c3prime / alpha3;
        return Math.min(255, Math.max(0, c3));
      };
      function mergeCanvases(canvas1, canvas2) {
        var context1 = canvas1.getContext("2d");
        var context2 = canvas2.getContext("2d");
        var image1data = context1.getImageData(0, 0, canvas1.width, canvas1.height);
        var image2data = context2.getImageData(0, 0, canvas2.width, canvas2.height);

        for (var pixel = 0; pixel < image1data.data.length; pixel += 4) {
          var r = image1data.data[pixel];
          var g = image1data.data[pixel + 1];
          var b = image1data.data[pixel + 2];
          var a = image1data.data[pixel + 3];
        
          var r2 = image2data.data[pixel];
          var g2 = image2data.data[pixel + 1];
          var b2 = image2data.data[pixel + 2];
          var a2 = image2data.data[pixel + 3];
          
          var a3 = getCompAlpha(a2, a);
          image2data.data[pixel+0] = getCompColor(r2, a2, r, a, a3);
          image2data.data[pixel+1] = getCompColor(g2, a2, g, a, a3);
          image2data.data[pixel+2] = getCompColor(b2, a2, b, a, a3);
          image2data.data[pixel+3] = a3;
        }
        context2.putImageData(image2data, 0, 0);
        
        var layer1 = canvas1.getAttribute('layer');
        var layer2 = canvas2.getAttribute('layer');
        $('canvas[layer=' + layer1 + ']').detach();
        $('li[layer=' + layer1 + ']').detach();
        $('li[layer=' + layer2 + '] img').attr('src', canvas2.toDataURL());
      };
      function mergeDown() {
        var handles = $('.handle[layer]');
        var layer1 = handles.get(0).getAttribute('layer');
        var layer2 = handles.get(1).getAttribute('layer');
        mergeCanvases(getCanvas(layer1), getCanvas(layer2));
      };
      function init() {
        $('canvas[layer]').each(function(index, item) {
          initCanvas(item);
        });
        $('#dom_handles').sortable({
          'update' : setLayerOrder
        });
        setLayerOrder();
      };
    </script>
  </head>
  <body onload="init();">
    <canvas layer="1" class="surface"></canvas>
    <canvas layer="2" class="surface"></canvas>
    <canvas layer="3" class="surface"></canvas>
    <canvas layer="4" class="surface"></canvas>
    <div id="controls">
      <ul id="dom_handles"></ul>
      <button onclick="mergeDown();">Merge Down</button>
    </div>
  </body>
</html>